package com.yupi.mianshiya.aop;

import com.yupi.mianshiya.annotation.DisruptorLock;
import com.yupi.mianshiya.common.ErrorCode;
import com.yupi.mianshiya.exception.BusinessException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class DisruptorLockInterceptor {
    @Autowired
    private RedissonClient redissonClient;

    @Around("@annotation(disruptorLock)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, DisruptorLock disruptorLock) throws Throwable {
        String lockKey = disruptorLock.key();
        long leaseTime = disruptorLock.leaseTime();
        long waitTime = disruptorLock.waitTime();
        TimeUnit timeUnit = disruptorLock.timeUnit();
        RLock lock = redissonClient.getLock(lockKey);
        boolean acquired = false;
        try {
           acquired = lock.tryLock(waitTime, leaseTime, timeUnit);
           if(acquired){
               return joinPoint.proceed();
           }
           else
               throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取锁失败");
        }catch (Throwable e){
            throw new Exception(e);
        }finally {
            if(acquired)
                lock.unlock();
        }
    }
}
